package com.hmdp.utils;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmdp.entity.SeckillVoucher;
import com.hmdp.entity.VoucherOrder;
import com.hmdp.service.ISeckillVoucherService;
import com.hmdp.service.IVoucherOrderService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 每天凌晨扫描 “创建时间> 30 分钟 + 未支付” 的订单，补充关单，防止延迟消息丢失导致的漏关单。
 */
@Slf4j
@Component
public class SeckillOrderCloseScheduledTask {

    @Autowired
    private IVoucherOrderService voucherOrderService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ISeckillVoucherService seckillVoucherService;

    // 每天凌晨0点执行（cron表达式：秒 分 时 日 月 周 年）
    @Scheduled(cron = "0 0 0 * * ?")
    public void closeTimeoutUnpaidOrder() throws InterruptedException {
        log.info("开始执行定时兜底关单任务，时间：{}", LocalDateTime.now());
        // 1. 分页查询超时未支付订单（30分钟以上未支付，避免一次性查太多）
        int pageNum = 1;
        int pageSize = 100; // 每页100条，可根据业务调整
        while (true) {
            // 查询条件：创建时间<当前时间-30分钟 + 状态=0（未支付）
            LocalDateTime timeoutTime = LocalDateTime.now().minusMinutes(30);
            List<VoucherOrder> timeoutOrders = voucherOrderService.lambdaQuery()
                    .lt(VoucherOrder::getCreateTime, timeoutTime)
                    .eq(VoucherOrder::getStatus, 0)
                    .page(new Page<>(pageNum, pageSize))
                    .getRecords();

            if (timeoutOrders.isEmpty()) {
                log.info("定时关单任务：第{}页无超时未支付订单，任务结束", pageNum);
                break;
            }
            // 2. 遍历处理每个订单（分布式锁+事务关单）
            for (VoucherOrder order : timeoutOrders) {
                    // 调用事务关单方法
                    voucherOrderService.handleCloseOrder(order);
            }
            pageNum++;
        }
        log.info("定时兜底关单任务执行完成，时间：{}", LocalDateTime.now());
    }

}